﻿using System;
using System.IO;
using Microsoft.SharePoint;

namespace RoketSolutions.SP2010.Infrostructure.Common.Extensions
{
    public static class SpListItem
    {
        public static object GetFieldValue(this SPListItem item, String fieldInternalName)
        {
            return item[item.Fields.GetFieldByInternalName(fieldInternalName).Id];
        }

        public static object GetFieldValue(this SPListItem item, Guid id)
        {
            return item[id];
        }

        public static String GetString(this SPListItem item, String fieldInternalName)
        {
            var objectValue = item.GetFieldValue(fieldInternalName);
            var stringValue = objectValue != null ? objectValue.ToString() : String.Empty;
            return stringValue;
        }

        public static String GetString(this SPListItem item, Guid id)
        {
            var objectValue = item.GetFieldValue(id);
            var stringValue = objectValue != null ? objectValue.ToString() : String.Empty;
            return stringValue;
        }

        public static String GetUrl(this SPListItem item, String fieldInternalName)
        {
            return new SPFieldUrlValue(item.GetString(fieldInternalName)).Url;
        }

        public static bool GetBoolean(this SPListItem item, String fieldInternalName)
        {
            bool result;
            return bool.TryParse(item.GetString(fieldInternalName), out result) && result;
        }

        public static bool GetBoolean(this SPListItem item, Guid id)
        {
            bool result;
            return bool.TryParse(item.GetString(id), out result) && result;
        }

        public static bool GetBoolean(this SPListItem item, String fieldInternalName, bool defaultValue)
        {
            bool result;
            return bool.TryParse(item.GetString(fieldInternalName), out result) ? result : defaultValue;
        }

        public static int GetInt(this SPListItem item, String fieldName)
        {
            return Convert.ToInt32(item[fieldName]);
        }

        public static double GetDouble(this SPListItem item, String fieldName)
        {
            return Convert.ToDouble(item[fieldName]);
        }

        public static DateTime? GetNullableDateTime(this SPListItem item, String fieldName)
        {
            var value = item.GetFieldValue(fieldName);
            return value != null ? Convert.ToDateTime(value) : (DateTime?)null;
        }

        public static int? GetNullableInt(this SPListItem item, String fieldName)
        {
            return item[fieldName] != null ? Convert.ToInt32(item[fieldName]) : (int?)item[fieldName];
        }

        public static float? GetNullableFloat(this SPListItem item, String fieldName)
        {
            return item[fieldName] != null ? float.Parse(item[fieldName].ToString()) : (float?)item[fieldName];
        }

        public static SPUser GetUser(this SPListItem item, String fieldName)
        {
            var fieldValue = GetUserValue(item, fieldName);
            return fieldValue != null ? fieldValue.User : null;
        }

        public static SPPrincipal GetPrincipal(this SPListItem item, String fieldName)
        {
            var fieldValue = GetUserValue(item, fieldName);
            if (fieldValue != null)
            {
                if (fieldValue.User != null)
                    return fieldValue.User;
                return item.Web.SiteGroups[fieldValue.LookupValue];
            }
            return null;
        }

        public static SPFieldUserValue GetUserValue(this SPListItem item, String fieldName)
        {
            var fieldValue = item.GetString(fieldName);
            return !String.IsNullOrEmpty(fieldValue) ? new SPFieldUserValue(item.Web, fieldValue) : null;
        }

        public static SPFieldLookupValue GetLookupValue(this SPListItem item, String fieldName)
        {
            var fieldValue = item.GetString(fieldName);
            return new SPFieldLookupValue(fieldValue);
        }

        public static SPFieldLookupValueCollection GetLookupValueCollection(this SPListItem item, String fieldName)
        {
            var fieldValue = item.GetString(fieldName);
            return new SPFieldLookupValueCollection(fieldValue);
        }

        public static void SetProperty(this SPListItem item, String fieldName, object value)
        {
            if (item.Fields.ContainsField(fieldName))
                item[fieldName] = value;
        }

        public static String GetDisplayFormUrl(this SPListItem item)
        {
            return String.Format("{0}/{1}?ID={2}", item.Web.Url, item.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url, item.ID);
        }

        public static String GetEditFormUrl(this SPListItem item)
        {
            return String.Format("{0}/{1}?ID={2}", item.Web.Url, item.ParentList.Forms[PAGETYPE.PAGE_EDITFORM].Url, item.ID);
        }

        public static String GetDisplayFormUrl(this SPList list, int id)
        {
            return String.Format("{0}/{1}?ID={2}", list.ParentWeb.Url, list.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url, id);
        }

        public static String GetEditFormUrl(this SPList list, int id)
        {
            return String.Format("{0}/{1}?ID={2}", list.ParentWeb.Url, list.Forms[PAGETYPE.PAGE_EDITFORM].Url, id);
        }
        public static SPFile GetAttachment(this SPListItem item, int index)
        {
            return item.Web.GetFile(String.Format("{0}{1}", item.Attachments.UrlPrefix, item.Attachments[index]));
        }

        public static void AddAttachment(this SPListItem item, String name, Stream stream)
        {
            if (stream == null)
                throw new ArgumentException("Bad attachment stream.");

            var data = new byte[stream.Length];
            stream.Read(data, 0, data.Length);

            AddAttachment(item, name, data);
        }

        public static void AddAttachment(this SPListItem item, String name, byte[] data)
        {
            if (String.IsNullOrEmpty(name))
                throw new ArgumentException("Attachment name can't be blank.");

            if (data == null || data.Length == 0)
                throw new ArgumentException("Attachment data can't be empty.");


            item.Attachments.Add(name, data);
        }
    }
}